Skip to content

feat(agent-memory): add access_strategy and tenant params for multitenancy#222

Draft
cassiofariasmachado wants to merge 7 commits into
mainfrom
feat/enable-multitenancy-support-for-agent-memory
Draft

feat(agent-memory): add access_strategy and tenant params for multitenancy#222
cassiofariasmachado wants to merge 7 commits into
mainfrom
feat/enable-multitenancy-support-for-agent-memory

Conversation

@cassiofariasmachado

@cassiofariasmachado cassiofariasmachado commented Jul 9, 2026

Copy link
Copy Markdown
Member

Disclaimer: Do not include SAP-internal or customer-specific information in this PR (e.g. internal system URLs, customer names, tenant IDs, or confidential configurations). This is a public repository.

Description

Adds multitenancy support to the agent_memory module. access_strategy and tenant are configured once at create_client() time — no per-call params on individual methods.

from sap_cloud_sdk.agent_memory import create_client, AccessStrategy

# Subscriber — all calls use subscriber token scoped to "acme-corp"
client = create_client(
    access_strategy=AccessStrategy.SUBSCRIBER,
    tenant="acme-corp",
)
memories = client.list_memories(agent_id="x", invoker_id="u")

# Provider — uses provider token (no isolation, emits logger.warning)
client = create_client(access_strategy=AccessStrategy.PROVIDER)

Implementation (native multitenancy approach)

This branch uses a single default binding with token URL derivation: the subscriber token URL is derived by replacing the identityzone segment in token_url with the tenant subdomain (using the identityzone field from the UAA binding). This is the intended implementation once the Agent Memory service natively supports multitenancy.

The companion PR #232 (feat/enable-multitenancy-support-for-agent-memory-using-bindings) implements the same public API but uses per-tenant bindings as a temporary workaround for environments where native multitenancy is not yet available.

Key changes

  • AccessStrategy enum (SUBSCRIBER / PROVIDER) on create_client()
  • AgentMemoryClient simplified: single _transport, access_strategy and tenant validated at construction, logger.warning() when PROVIDER is used
  • _http_transport.py unchanged — per-tenant token derivation via identityzone remains
  • BDD integration tests with full subscriber + provider coverage sharing all step implementations

Related Issue

Closes #

Type of Change

  • Bug fix
  • New feature (non-breaking)
  • Breaking change
  • Documentation update

How to Test

pytest tests/agent_memory/unit/    # 248 tests pass
CLOUD_SDK_CFG_HANA_AGENT_MEMORY_DEFAULT_SUBSCRIBER_TENANT=<subdomain> \
pytest tests/agent_memory/integration/   # 26 pass

Checklist

  • Tests added/updated
  • All tests pass locally
  • Pre-commit hooks pass (uvx pre-commit run --all-files)
  • Documentation updated
  • No sensitive information

Breaking Changes

create_client() with no args raises AgentMemoryValidationError (default SUBSCRIBER requires tenant). Individual methods no longer accept access_strategy or tenant.

Migration:

client = create_client(tenant="my-subdomain")          # subscriber
client = create_client(access_strategy=AccessStrategy.PROVIDER)  # provider

| Value | Description |
| --------------------------- | ------------------------------------------------------------------ |
| `SUBSCRIBER_ONLY` (default) | Reads and writes against the subscriber tenant. Requires `tenant`. |
| `PROVIDER_ONLY` | Reads and writes against the provider tenant. No `tenant` needed. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be useful to note that there is no tenant isolation in this case, just to make the consequences of enabling provider very clear.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I've updated the documentation to make it clear.

- create_client() and AgentMemoryClient.__init__ accept access_strategy
  (default SUBSCRIBER_ONLY) and tenant as constructor params
- _resolve_tenant is now an instance method; per-call params override
  instance defaults
- All method signatures change to Optional[AccessStrategy] = None
  (sentinel: use instance default)
- user-guide: add client-level configuration section and PROVIDER_ONLY
  isolation warning
- tests: update TestAccessStrategy and TestCreateClient for instance method
@cassiofariasmachado
cassiofariasmachado force-pushed the feat/enable-multitenancy-support-for-agent-memory branch from 3282daf to db9ba9b Compare July 14, 2026 20:40
… warning

- SUBSCRIBER_ONLY → SUBSCRIBER, PROVIDER_ONLY → PROVIDER across all
  agent_memory source, tests, feature files, and user guide
- Add logger.warning() when AccessStrategy.PROVIDER is used, making
  the no-isolation behaviour explicit at runtime
- Remove access_strategy/tenant per-call params from all 13 methods
- Validate access_strategy/tenant at __init__ time (same as bindings branch)
- Store self._tenant at init; pass tenant_subdomain=self._tenant to transport
  on every call (preserves identityzone token URL derivation internally)
- Update tests: remove _resolve_tenant tests, add init-time validation tests,
  remove per-call kwargs from all call sites
- Public API now identical to feat/enable-multitenancy-support-for-agent-memory-using-bindings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants